/**
 * 验证模块 - 借鉴validator.js的设计理念
 * 提供各种常用的数据验证功能
 */

// 预编译正则表达式缓存
const REGEX_PATTERNS = {
  // 手机号（宽松）- 1开头，第二位3-9，总长11位
  phone: /^1[3-9]\d{9}$/,

  // 手机号（严格）- 精确匹配运营商号段（排除134）
  phoneStrict: /^((13[0-3])|(13[5-9])|(14(0|[5-7]|9))|(15([0-3]|[5-9]))|(16(2|[5-7]))|(17[0-8])|(18[0-9])|(19([0-3]|[5-9])))\d{8}$/,

  // 座机号（宽松）- 3-4位区号 + 7-8位号码
  tel: /^(\d{3,4}|\d{3,4}-)?\d{7,8}$/,

  // 座机号（严格）
  telStrict: /^(([0-9]{3,4}-)?[0-9]{7,8})$/,

  // 身份证号（18位）
  idCard: /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/,

  // 邮箱
  email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,

  // URL
  url: /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/,

  // 中文字符
  chinese: /^[\u4e00-\u9fa5]+$/,

  // 中文姓名（2-8个中文字符，支持·）
  chineseName: /^[\u4e00-\u9fa5·]{2,8}$/,

  // IP地址
  ip: /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,

  // MAC地址
  mac: /^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$/,

  // 银行卡号（13-19位数字）
  bankCard: /^\d{13,19}$/,

  // 车牌号
  licensePlate: /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/,

  // 社会统一信用代码
  socialCreditCode: /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/,

  // 护照号码
  passport: /^[a-zA-Z0-9]{5,17}$/,

  // QQ号
  qq: /^[1-9][0-9]{4,10}$/,

  // 微信号
  wechat: /^[a-zA-Z][a-zA-Z0-9_-]{5,19}$/
};

// 省份代码映射（用于身份证严格验证）
const PROVINCE_CODES = {
  11: '北京', 12: '天津', 13: '河北', 14: '山西', 15: '内蒙古',
  21: '辽宁', 22: '吉林', 23: '黑龙江', 31: '上海', 32: '江苏',
  33: '浙江', 34: '安徽', 35: '福建', 36: '江西', 37: '山东',
  41: '河南', 42: '湖北', 43: '湖南', 44: '广东', 45: '广西',
  46: '海南', 50: '重庆', 51: '四川', 52: '贵州', 53: '云南',
  54: '西藏', 61: '陕西', 62: '甘肃', 63: '青海', 64: '宁夏',
  65: '新疆', 71: '台湾', 81: '香港', 82: '澳门'
};

/**
 * 弹窗测试函数
 * @param {string} message 要显示的消息
 */
export function alert(message) {
  if (typeof window !== 'undefined' && window.alert) {
    // eslint-disable-next-line no-alert
    window.alert(message);
  } else {
    // eslint-disable-next-line no-console
    console.log(message);
  }
}

/**
 * 检查值是否为空
 * @param {any} value 要检查的值
 * @returns {boolean} 是否为空
 */
export function isEmpty(value) {
  return value === null ||
         value === undefined ||
         value === '' ||
         value === 'null' ||
         value === 'undefined' ||
         (typeof value === 'string' && value.trim() === '') ||
         (Array.isArray(value) && value.length === 0) ||
         (typeof value === 'object' && Object.keys(value).length === 0);
}

/**
 * 验证手机号（宽松模式）
 * @param {string} phone 手机号
 * @returns {boolean} 是否有效
 */
export function isPhone(phone) {
  if (typeof phone !== 'string') return false;
  return REGEX_PATTERNS.phone.test(phone);
}

/**
 * 验证手机号（严格模式）
 * @param {string} phone 手机号
 * @returns {boolean} 是否有效
 */
export function isPhoneStrict(phone) {
  if (typeof phone !== 'string') return false;
  return REGEX_PATTERNS.phoneStrict.test(phone);
}

/**
 * 验证座机号（宽松模式）
 * @param {string} tel 座机号
 * @returns {boolean} 是否有效
 */
export function isTel(tel) {
  if (typeof tel !== 'string') return false;
  return REGEX_PATTERNS.tel.test(tel);
}

/**
 * 验证座机号（严格模式）
 * @param {string} tel 座机号
 * @returns {boolean} 是否有效
 */
export function isTelStrict(tel) {
  if (typeof tel !== 'string') return false;
  return REGEX_PATTERNS.telStrict.test(tel);
}

/**
 * 验证身份证号（简单模式）
 * @param {string} idCard 身份证号
 * @returns {boolean} 是否有效
 */
export function isIdCard(idCard) {
  if (typeof idCard !== 'string') return false;
  return REGEX_PATTERNS.idCard.test(idCard);
}

/**
 * 验证身份证号（严格模式 - 包含省份、日期、校验码验证）
 * @param {string} idCard 身份证号
 * @returns {boolean} 是否有效
 */
export function isIdCardStrict(idCard) {
  if (!isIdCard(idCard)) return false;

  // 验证省份代码
  const provinceCode = parseInt(idCard.substring(0, 2), 10);
  if (!PROVINCE_CODES[provinceCode]) return false;

  // 验证日期
  const year = parseInt(idCard.substring(6, 10), 10);
  const month = parseInt(idCard.substring(10, 12), 10);
  const day = parseInt(idCard.substring(12, 14), 10);

  const date = new Date(year, month - 1, day);
  if (date.getFullYear() !== year ||
      date.getMonth() !== month - 1 ||
      date.getDate() !== day) {
    return false;
  }

  // 验证校验码
  const factors = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
  const parityBits = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];

  let sum = 0;
  for (let i = 0; i < 17; i++) {
    sum += parseInt(idCard[i], 10) * factors[i];
  }

  const expectedCheckCode = parityBits[sum % 11];
  const actualCheckCode = idCard[17].toUpperCase();

  return expectedCheckCode === actualCheckCode;
}

/**
 * 验证邮箱地址
 * @param {string} email 邮箱地址
 * @returns {boolean} 是否有效
 */
export function isEmail(email) {
  if (typeof email !== 'string') return false;
  return REGEX_PATTERNS.email.test(email);
}

/**
 * 验证URL
 * @param {string} url URL地址
 * @returns {boolean} 是否有效
 */
export function isUrl(url) {
  if (typeof url !== 'string') return false;
  return REGEX_PATTERNS.url.test(url);
}

/**
 * 验证中文字符
 * @param {string} text 文本
 * @returns {boolean} 是否全为中文
 */
export function isChinese(text) {
  if (typeof text !== 'string') return false;
  return REGEX_PATTERNS.chinese.test(text);
}

/**
 * 验证中文姓名
 * @param {string} name 姓名
 * @returns {boolean} 是否有效的中文姓名
 */
export function isChineseName(name) {
  if (typeof name !== 'string') return false;
  return REGEX_PATTERNS.chineseName.test(name);
}

/**
 * 验证IP地址
 * @param {string} ip IP地址
 * @returns {boolean} 是否有效
 */
export function isIP(ip) {
  if (typeof ip !== 'string') return false;
  return REGEX_PATTERNS.ip.test(ip);
}

/**
 * 验证MAC地址
 * @param {string} mac MAC地址
 * @returns {boolean} 是否有效
 */
export function isMAC(mac) {
  if (typeof mac !== 'string') return false;
  return REGEX_PATTERNS.mac.test(mac);
}

/**
 * 验证银行卡号
 * @param {string} cardNumber 银行卡号
 * @returns {boolean} 是否有效
 */
export function isBankCard(cardNumber) {
  if (typeof cardNumber !== 'string') return false;

  if (!REGEX_PATTERNS.bankCard.test(cardNumber)) return false;

  // Luhn算法验证
  let sum = 0;
  let alternate = false;

  for (let i = cardNumber.length - 1; i >= 0; i--) {
    let n = parseInt(cardNumber[i], 10);

    if (alternate) {
      n *= 2;
      if (n > 9) n = (n % 10) + 1;
    }

    sum += n;
    alternate = !alternate;
  }

  return sum % 10 === 0;
}

/**
 * 验证车牌号
 * @param {string} plate 车牌号
 * @returns {boolean} 是否有效
 */
export function isLicensePlate(plate) {
  if (typeof plate !== 'string') return false;
  return REGEX_PATTERNS.licensePlate.test(plate);
}

/**
 * 验证社会统一信用代码
 * @param {string} code 信用代码
 * @returns {boolean} 是否有效
 */
export function isSocialCreditCode(code) {
  if (typeof code !== 'string') return false;
  return REGEX_PATTERNS.socialCreditCode.test(code);
}

/**
 * 验证护照号码
 * @param {string} passport 护照号
 * @returns {boolean} 是否有效
 */
export function isPassport(passport) {
  if (typeof passport !== 'string') return false;
  return REGEX_PATTERNS.passport.test(passport);
}

/**
 * 验证QQ号
 * @param {string} qq QQ号
 * @returns {boolean} 是否有效
 */
export function isQQ(qq) {
  if (typeof qq !== 'string') return false;
  return REGEX_PATTERNS.qq.test(qq);
}

/**
 * 验证微信号
 * @param {string} wechat 微信号
 * @returns {boolean} 是否有效
 */
export function isWechat(wechat) {
  if (typeof wechat !== 'string') return false;
  return REGEX_PATTERNS.wechat.test(wechat);
}

/**
 * 检查登录状态
 * @returns {boolean} 是否已登录
 */
export function checkLogin() {
  if (typeof localStorage === 'undefined') return false;

  const userphone = localStorage.getItem('userphone');
  return userphone && userphone !== '' && userphone !== 'undefined';
}

/**
 * 验证密码强度
 * @param {string} password 密码
 * @param {Object} options 选项
 * @returns {Object} 验证结果
 */
export function validatePassword(password, options = {}) {
  const {
    minLength = 6,
    maxLength = 20,
    requireUppercase = false,
    requireLowercase = false,
    requireNumbers = false,
    requireSpecialChars = false
  } = options;

  const result = {
    valid: true,
    score: 0,
    errors: []
  };

  if (typeof password !== 'string') {
    result.valid = false;
    result.errors.push('密码必须是字符串');
    return result;
  }

  if (password.length < minLength) {
    result.valid = false;
    result.errors.push(`密码长度至少${minLength}位`);
  }

  if (password.length > maxLength) {
    result.valid = false;
    result.errors.push(`密码长度最多${maxLength}位`);
  }

  if (requireUppercase && !/[A-Z]/.test(password)) {
    result.valid = false;
    result.errors.push('密码必须包含大写字母');
  } else if (/[A-Z]/.test(password)) {
    result.score += 1;
  }

  if (requireLowercase && !/[a-z]/.test(password)) {
    result.valid = false;
    result.errors.push('密码必须包含小写字母');
  } else if (/[a-z]/.test(password)) {
    result.score += 1;
  }

  if (requireNumbers && !/\d/.test(password)) {
    result.valid = false;
    result.errors.push('密码必须包含数字');
  } else if (/\d/.test(password)) {
    result.score += 1;
  }

  if (requireSpecialChars && !/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(password)) {
    result.valid = false;
    result.errors.push('密码必须包含特殊字符');
  } else if (/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(password)) {
    result.score += 1;
  }

  // 长度加分
  if (password.length >= 8) result.score += 1;
  if (password.length >= 12) result.score += 1;

  return result;
}
